package edu.gdkm.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class MyAspect {

    @Before("edu.gdkm.aop.SystemArchitecture.inDataAccessLayer()")
    public void myBefore(JoinPoint joinPoint) {
        System.out.println("-------------前置通知-------------"+joinPoint.getSignature().getName());
    }


    @AfterReturning("edu.gdkm.aop.SystemArchitecture.inDataAccessLayer()")
    public void myAfterReturning() {
        System.out.println("-------------后置通知-------------");
    }

    // returnVal 就是相应方法的返回值
    @AfterReturning(
            value="edu.gdkm.aop.SystemArchitecture.inDataAccessLayer()",
            returning="returnVal")
    public void myAfterReturning(Object returnVal) {
        //  ... 实现代码
        System.out.println("-------------后置通知-------------："+returnVal);
    }
    // 这种最灵活，既能做 @Before 的事情，也可以做 @AfterReturning 的事情
    @Around("edu.gdkm.aop.SystemArchitecture.inDataAccessLayer()")
    public Object myAround(ProceedingJoinPoint pjp) throws Throwable {
        //  target 方法执行前... 实现代码
        System.out.println("-------------环绕开始-------------");
        Object obj = pjp.proceed();
        //  target 方法执行后... 实现代码
        System.out.println("-------------环绕结束-------------");
        return obj;
    }
    // 异常返回的时候
    @AfterThrowing(value = "edu.gdkm.aop.SystemArchitecture.inDataAccessLayer()",throwing = "e")
    public void myAfterThrowing(Throwable e) {
        System.out.println("异常通知："+e);
    }

    // 注意理解它和 @AfterReturning 之间的区别，这里会拦截正常返回和异常的情况
    @After("edu.gdkm.aop.SystemArchitecture.inDataAccessLayer()")
    public void myAfter() {
        // 通常就像 finally 块一样使用，用来释放资源。
        // 无论正常返回还是异常退出，都会被拦截到
        System.out.println("-------------最终通知-------------");
    }




}
